package cn.skycity.common.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.util.StrUtil;
import cn.skycity.common.mapper.SysMenuMapper;
import cn.skycity.common.service.ISysMenuService;
import cn.skycity.framework.core.exception.ServiceException;
import cn.skycity.framework.core.utils.LangUtil;
import cn.skycity.framework.core.utils.TreeBuildUtils;
import cn.skycity.framework.core.utils.UserUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.skycity.framework.uaa.pojo.entity.SysMenu;
import com.skycity.framework.uaa.pojo.vo.RouteVO;
import com.skycity.framework.uaa.pojo.vo.SelectVO;
import com.skycity.framework.uaa.pojo.vo.SysMenuVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;


/**
 * 菜单业务类
 *
 * @author
 * @date 2020-11-06
 */
@Service
@Slf4j
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements ISysMenuService {
//    @Resource
//    private  ISysPermissionService permissionService;

    /**
     * 菜单表格（Table）层级列表
     *
     * @param name 菜单名称
     * @return
     */
//    @Override
//    public List<RouteVO> listTable(String name) {
//        List<SysMenu> menuList = this.list(new LambdaQueryWrapper<SysMenu>().orderByAsc(SysMenu::getSort));
//        return recursionRoute(0L, menuList);
//    }

    /**
     * 菜单下拉（Select）层级列表
     *
     * @return
     */
//    @Override
//    public List<SelectVO> listSelect() {
//        List<SysMenu> menuList = this.list(new LambdaQueryWrapper<SysMenu>().orderByAsc(SysMenu::getSort));
//        return recursionSelectList(0L, menuList);
//    }


    /**
     * 递归生成菜单下拉层级列表
     *
     * @param parentId 父级ID
     * @param menuList 菜单列表
     * @return
     */
    private static List<SelectVO> recursionSelectList(Long parentId, List<SysMenu> menuList) {
        List<SelectVO> menuSelectList = new ArrayList<>();
        Optional.ofNullable(menuList).orElse(new ArrayList<>())
                .stream()
                .filter(menu -> menu.getParentId().equals(parentId))
                .forEach(menu -> {
//                    SelectVO selectVO = new SelectVO(menu.getId(), menu.getName());
//                    List<SelectVO> children = recursionSelectList(menu.getId(), menuList);
//                    if (CollectionUtil.isNotEmpty(children)) {
//                        selectVO.setChildren(children);
//                    }
//                    menuSelectList.add(selectVO);
                });
        return menuSelectList;
    }


    /**
     * 菜单路由（Route）层级列表
     * 列出所有菜单
     * 列出当前用户所有菜单的权限，如果有这个菜单的权限，则设置为true,过滤掉没有权限的菜单角色
     * 读多写少，缓存至Redis
     *
     * @return
     * @Cacheable cacheNames:缓存名称，不同缓存的数据是彼此隔离； key: 缓存Key。
     */
    @Override
//    @Cacheable(cacheNames = "system", key = "'routeList'")
    public List<RouteVO> listRoute() {
        List<SysMenu> menuList = baseMapper.listAllMenus();
        List<Long> authMenuIds = baseMapper.listAuthMenuIds(UserUtils.getUserName());
        List<SysMenu> authList = menuList.stream().filter(item -> authMenuIds.contains(item.getId())).toList();
        return recursionRoute2(0L, authList);
    }


    private List<RouteVO> recursionRoute2(Long parentId, List<SysMenu> menuList) {
        List<RouteVO> list = new ArrayList<>();
        Optional.ofNullable(menuList).ifPresent(menus -> menus.stream().filter(menu -> menu.getParentId().equals(parentId))
                .forEach(menu -> {
                    RouteVO routeVO = new RouteVO();
//                    routeVO.setId(menu.getId());
//                    routeVO.setParentId(menu.getParentId());
                    routeVO.setName(getMenuName(menu.getMenuName()));
                    routeVO.setPath(menu.getRouterPath()); // 根据path路由跳转 this.$router.push({name:xxx})
                    routeVO.setComponent(menu.getComponentInfo());
//                    routeVO.setRedirect(menu.getRedirect());
//                    routeVO.setLink(menu.getLink());
//                    routeVO.setSort(menu.getSort());
//                    routeVO.setMenuType(menu.getMenuType());
//                    routeVO.setPerm(menu.getPerms());
//                    routeVO.setStatus(menu.getStatus());

                    RouteVO.Meta meta = new RouteVO.Meta(routeVO.getName(), menu.getIcon());
//                    meta.setKeepAlive(true);
//                    meta.setAffix(GlobalConstants.STATUS_YES.equals(menu.getAffix()));
//                    meta.setVisible(GlobalConstants.STATUS_YES.equals(menu.getStatus()));
//                    meta.setLink(StrUtil.isNotEmpty(menu.getLink()));
//                    meta.setTitle(menu.getTitle());
//                    meta.setBigScreen(GlobalConstants.STATUS_YES.equals(menu.getBigScreen()));
//                    meta.setComponent(menu.getComponent());
                    routeVO.setMeta(meta);
                    //递归获取子菜单
                    List<RouteVO> children = recursionRoute2(menu.getId(), menuList);
                    routeVO.setChildren(children);
                    list.add(routeVO);
                }));
        return list;

    }

    /**
     * 递归生成菜单路由层级列表
     *
     * @param parentId 父级ID
     * @param menuList 菜单列表
     * @return
     */
    private List<RouteVO> recursionRoute(Long parentId, List<SysMenu> menuList) {
        List<RouteVO> list = new ArrayList<>();
        Optional.ofNullable(menuList).ifPresent(menus -> menus.stream().filter(menu -> menu.getParentId().equals(parentId) && !"2".equals(menu.getMenuType()))
                .forEach(menu -> {
                    RouteVO routeVO = new RouteVO();
                    routeVO.setId(menu.getId());
                    routeVO.setParentId(menu.getParentId());
                    routeVO.setName(getMenuName(menu.getMenuName()));
                    routeVO.setPath(menu.getPath()); // 根据path路由跳转 this.$router.push({name:xxx})
                    routeVO.setComponent(menu.getComponent());
//                    routeVO.setRedirect(menu.getRedirect());
//                    routeVO.setLink(menu.getLink());
                    routeVO.setSort(menu.getSort());
                    routeVO.setMenuType(menu.getMenuType());
                    routeVO.setPerm(menu.getPerms());
                    routeVO.setStatus(menu.getStatus());

                    RouteVO.Meta meta = new RouteVO.Meta(routeVO.getName(), menu.getIcon());
//                    meta.setKeepAlive(true);
//                    meta.setAffix(GlobalConstants.STATUS_YES.equals(menu.getAffix()));
//                    meta.setVisible(GlobalConstants.STATUS_YES.equals(menu.getStatus()));
//                    meta.setLink(StrUtil.isNotEmpty(menu.getLink()));
//                    meta.setTitle(menu.getTitle());
//                    meta.setBigScreen(GlobalConstants.STATUS_YES.equals(menu.getBigScreen()));
//                    meta.setComponent(menu.getComponent());
                    routeVO.setMeta(meta);
                    //递归获取子菜单
                    List<RouteVO> children = recursionRoute(menu.getId(), menuList);
                    routeVO.setChildren(children);
                    list.add(routeVO);
                }));
        return list;

    }

    /**
     * 菜单下拉（TreeSelect）层级列表
     *
     * @return
     */
    @Override
    public List<RouteVO> listTreeSelect(SysMenu menu) {
        List<SysMenu> menuList = list(new LambdaQueryWrapper<SysMenu>()
                .like(StrUtil.isNotEmpty(menu.getMenuName()), SysMenu::getMenuName, menu.getMenuName())
                .eq(menu.getStatus() != null, SysMenu::getStatus, menu.getStatus()).orderByAsc(SysMenu::getSort));
        return recursionRoute(0L, menuList);
    }

    /**
     * 新增菜单
     *
     * @param menu
     * @return
     */
    @Override
    public boolean saveMenu(SysMenu menu) {
        Long pathCount = baseMapper.selectCount(new LambdaQueryWrapper<SysMenu>().eq(SysMenu::getPath, menu.getPath()));
        if (pathCount > 0) {
            throw new ServiceException(LangUtil.getMessage("menu.path.exist"));
        }
        menu.setParentId(menu.getParentId() == null ? 0 : menu.getParentId());
        if ("2".equals(menu.getMenuType())) {
            menu.setComponent(null);
        }
        boolean result = this.save(menu);
        if (result) {
//            permissionService.refreshPermRolesRules();
        }
        return result;
    }

    /**
     * 修改菜单
     *
     * @param menu
     * @return
     */
    @Override
    public boolean updateMenu(SysMenu menu) {
        if (menu.getParentId() == null) {
            menu.setParentId(0L);
        }
        boolean result = this.updateById(menu);
        if (result) {
//            permissionService.refreshPermRolesRules();
        }
        return result;
    }

    @Override
    public List<SysMenuVo> selectMenuList() {
        List<SysMenu> list = baseMapper.selectMenuList();
        return BeanUtil.copyToList(list, SysMenuVo.class);
    }

    @Override
    public List<Tree<Long>> buildMenuTreeSelect(List<SysMenuVo> menus) {
        if (CollUtil.isEmpty(menus)) {
            return CollUtil.newArrayList();
        }
        return TreeBuildUtils.build(menus, (menu, tree) ->{
            tree.setId(menu.getId())
                    .setParentId(menu.getParentId())
                    .setName(menu.getMenuName())
                    .setWeight(menu.getOrderNum());
            tree.put("icon",menu.getIcon());
            tree.put("menuType",menu.getMenuType());
        });
    }


//    /**
//     * 递归生成菜单下拉(TreeSelect)层级列表
//     *
//     * @param parentId 父级ID
//     * @param menuList 菜单列表
//     * @return
//     */
//    private static List<TreeSelectVO> recursionTreeSelectList(Long parentId, List<SysMenu> menuList) {
//        List<TreeSelectVO> menuSelectList = new ArrayList<>();
//        Optional.ofNullable(menuList).orElse(new ArrayList<>())
//                .stream()
//                .filter(menu -> menu.getParentId().equals(parentId))
//                .forEach(menu -> {
//                    TreeSelectVO selectVO = TreeSelectVO.builder().id(menu.getId()).label(getMenuName(menu.getTitle()))
//                            .icon(menu.getIcon()).sort(menu.getSort()).perm(menu.getPerm()).status(menu.getStatus())
//                            .component(menu.getComponent()).createTime(menu.getCreateTime()).path(menu.getPath())
//                            .parentId(menu.getParentId()==0?null:menu.getParentId()).title(menu.getTitle()).menuType(menu.getMenuType())
//                            .build();
//                    List<TreeSelectVO> children = recursionTreeSelectList(menu.getId(), menuList);
//                    if (CollectionUtil.isNotEmpty(children)) {
//                        selectVO.setChildren(children);
//                    }
//                    menuSelectList.add(selectVO);
//                });
//        return menuSelectList;
//    }

    private static String getMenuName(String title) {
//        JSONObject jsonObject = JSONUtil.parseObj(title);
//        Locale locale = LocaleContextHolder.getLocale();
//        return jsonObject.getStr(locale.toString().replace("_","-"));
        return title;
    }


    @Override
    public List<Long> selectMenuListByRoleId(Long roleId) {
//        SysRole role = roleMapper.selectById(roleId);
        return baseMapper.selectMenuListByRoleId(roleId);
    }
}
